#!/bin/bash
############################################################################
# Copyright (C) 2007 Lawrence Livermore National Security, LLC
# Produced at Lawrence Livermore National Laboratory.
# Written by Jim Garlick <garlick@llnl.gov>.
# UCRL-CODE-235119
# 
# This file is part of nfsroot, a network root file system utility.
# 
# nfsroot is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# nfsroot is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with nfsroot; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
############################################################################
#
# rc.nfsroot-kdump - nfsroot startup (special kdump hook)
#
# If there is a /proc/vmcore, save it and reboot.
#
prog=rc.nfsroot-kdump
configfile=/etc/sysconfig/nfsroot
KDUMP_DIR_MOUNTOPTS="nfsvers=3,rw,nolock"
KDUMP_LEVEL=31
KDUMP_FAILSAFE=reboot
if [ -f $configfile ]; then
   . $configfile
fi
export PATH=/bin:/sbin:/usr/bin:/usr/sbin

kdump_panic() {
   case "${KDUMP_FAILSAFE}" in
   shell)
      echo "${prog}: spawning shell so you can save /proc/vmcore manually" >&2
      echo "${prog}: system will reboot when you exit this shell" >&2
      bash --login
      ;;
   reboot)
      echo "${prog}: giving up and rebooting" >&2
      ;;
   esac
   reboot -f
}

guess_kdump_dir () {
   local dir=${1:-/var/crash}
   local host
   (while read line; do
      set $line
      if [ "$2" = "/" ] && echo $1|grep -q ":"; then
          echo "$(echo $1|sed 's/:.*//'):$dir"
          break
      fi
   done) </proc/mounts
}

# some verification in the non-kexec context
kdump_sanity()
{
   local ird=/boot/initrd-$(uname -r)
   local img=${ird}kdump.img

   if ! [ -f ${img} ]; then
         echo "${prog}: ${img} does not exist" >&2
         echo "${prog}: run nfsroot-kdumplinks on root server and reboot me" >&2
         sleep 86400
   fi
   if [ -f /etc/kdump.conf ]; then
      if [ $(stat -c "%Y" /etc/kdump.conf) -gt $(stat -c "%Y" ${img}) ]; then
         echo "${prog}: /etc/kdump.conf is newer than ${img}" >&2
         echo "${prog}: run nfsroot-kdumplinks on root server and reboot me" >&2
         sleep 86400
      fi
   fi
}

# FIXME: is there a better method of detecting kexec context?
if ! grep -q memmap=exactmap /proc/cmdline; then
   echo "${prog}: kernel was not booted via kexec" >&2
   kdump_sanity
   return 1
fi

if ! [ -s /proc/vmcore ]; then
   echo "${prog}: no vmcore is available" >&2
   reboot -f
fi
if [ -z "$KDUMP_DIR" ] || ! [[ "$KDUMP_DIR" =~ .*:.* ]]; then
   KDUMP_DIR=$(guess_kdump_dir $KDUMP_DIR)
fi
if [ -z "$KDUMP_DIR" ]; then
   echo "${prog}: could not guess KDUMP_DIR" >&2
   kdump_panic
fi

if ! mount -n -o ${KDUMP_DIR_MOUNTOPTS} ${KDUMP_DIR} /var/crash; then
   echo "${prog}: mount -n -o ${KDUMP_DIR_MOUNTOPTS} ${KDUMP_DIR} /var/crash failed" >&2
   kdump_panic
fi

# FIXME: localtime assumption may not be correct
hwclock --hctosys --localtime
mount -n -t tmpfs /tmp /tmp
corefile=/var/crash/vmcore-$(hostname)-$(date +%Y-%m-%d-%T)
vmlinux=/boot/vmlinux-$(uname -r)
makedumpfile="makedumpfile -c -d ${KDUMP_LEVEL}"
if [ -r $vmlinux ]; then
   makedumpfile="$makedumpfile -x ${vmlinux}"
else
   echo "${prog}: no $vmlinux: dropping -x option to makedumpfile" >&2
fi
makedumpfile="$makedumpfile /proc/vmcore ${corefile}"
echo "${prog}: copying vmcore"
#echo "${prog}: $makedumpfile" >&2
if ! $makedumpfile; then
   echo "${prog}: copy failed" >&2
   kdump_panic
fi
echo "${prog}: copy successful" >&2
umount -n /tmp
umount -n /var/crash
reboot -f || exit 1
